package com.sinosoft.vaccinetoai.common.mapper.extend;

import cn.hutool.core.util.StrUtil;
import com.sinosoft.vaccinetoai.common.mapper.extend.annotation.Operator;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.annotation.Version;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

import java.util.Set;

/**
 * 扩展Sql Provider 根据IO查询
 * @author xzh
 * @date 2022-10-24 14:38
 * @since 5.0.0
 */
public class ExtendSelectByIOProvider extends MapperTemplate {

    public ExtendSelectByIOProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public String selectByIO(MappedStatement ms) {
        Class<?> entityClass = ms.getResultMaps().get(0).getType();
        Class<?> parameterClass = getEntityClass(ms);
        //修改返回值类型为实体类型
        setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
        sql.append(whereAllIfColumns(parameterClass, isNotEmpty()));
        sql.append(SqlHelper.orderByDefault(parameterClass));
        return sql.toString();
    }

    /**
     * where所有列的条件，会判断是否!=null
     *
     * @param entityClass
     * @param empty
     * @return
     */
    private static String whereAllIfColumns(Class<?> entityClass, boolean empty) {
        return whereAllIfColumns(entityClass, empty, false);
    }

    /**
     * where所有列的条件，会判断是否!=null
     *
     * @param entityClass
     * @param empty
     * @param useVersion
     * @return
     */
    private static String whereAllIfColumns(Class<?> entityClass, boolean empty, boolean useVersion) {
        StringBuilder sql = new StringBuilder();
        boolean hasLogicDelete = false;

        sql.append("<where>");
        //获取全部列
        Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
        EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);
        //当某个列有主键策略时，不需要考虑他的属性是否为空，因为如果为空，一定会根据主键策略给他生成一个值
        for (EntityColumn column : columnSet) {
            if (!useVersion || !column.getEntityField().isAnnotationPresent(Version.class)) {
                // 逻辑删除，后面拼接逻辑删除字段的未删除条件
                if (logicDeleteColumn != null && logicDeleteColumn == column) {
                    hasLogicDelete = true;
                    continue;
                }
                // 运算符
                String operator = "=";
                if(column.getEntityField().isAnnotationPresent(Operator.class)) {
                    operator = column.getEntityField().getAnnotation(Operator.class).value();
                }
                sql.append(SqlHelper.getIfNotNull(column, StrUtil.join(" ", " AND", column.getColumn(), operator, column.getColumnHolder()), empty));
            }
        }
        if (useVersion) {
            sql.append(SqlHelper.whereVersion(entityClass));
        }
        if (hasLogicDelete) {
            sql.append(SqlHelper.whereLogicDelete(entityClass, false));
        }

        sql.append("</where>");
        return sql.toString();
    }

}
